﻿using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json; 

namespace TianYu.Core.Common
{
    /// <summary>
    /// Json扩展方法类
    /// </summary>
    public static class JsonExtensions
    {
        #region 字符串扩展
        /// <summary>
        /// 将当前Json字符串转为T类对象
        /// </summary>
        /// <typeparam name="T">类对象</typeparam>
        /// <param name="Json">Json字符串</param>
        /// <returns>T类对象</returns>
        public static T ToJsonObject<T>(this string Json) where T : class
        {
            return string.IsNullOrEmpty(Json) ? default(T) : JsonHelper.DeserializeObject<T>(Json);
        }
        /// <summary>
        /// 将当前Json字符串转为Json对象
        /// </summary>
        /// <param name="Json">Json字符串</param>
        /// <returns>Json对象</returns>
        public static dynamic ToJsonObject(this string Json)
        {
            return string.IsNullOrEmpty(Json) ? null : JsonHelper.DeserializeObject(Json);
        }
        #endregion

        #region 对象扩展
        /// <summary>
        /// 将对象转为Json字符串
        /// </summary>
        /// <param name="obj">对象</param>
        /// <returns>Json字符串</returns>
        public static string ToJsonString(this object obj)
        {
            var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
            return JsonHelper.SerializeObject(obj, timeConverter);
        }

        /// <summary>
        /// 将对象转为Json字符串
        /// </summary>
        /// <param name="obj">对象</param>
        /// <param name="datetimeformats">日期格式化（如：yyyy-MM-dd HH:mm:ss）</param>
        /// <returns>Json字符串</returns>
        public static string ToJsonString(this object obj, string datetimeformats)
        {
            var timeConverter = new IsoDateTimeConverter { DateTimeFormat = datetimeformats };
            return JsonHelper.SerializeObject(obj, timeConverter);
        }
        #endregion

        public static string StringValue(this JToken @this, string key) => @this.Value<string>(Check.NotEmpty(key, nameof(key)));

        public static int IntValue(this JToken @this, string key) => @this.Value<int>(Check.NotEmpty(key, nameof(key)));

        public static float FloatValue(this JToken @this, string key) => @this.Value<float>(Check.NotEmpty(key, nameof(key)));
    }

    public class CustomContractResolver : CamelCasePropertyNamesContractResolver
    {
        /// <summary>
        /// 对长整型做处理
        /// </summary>
        /// <param name="objectType"></param>
        /// <returns></returns>
        protected override JsonConverter ResolveContractConverter(Type objectType)
        {
            if (objectType == typeof(long))
            {
                return new JsonConverterLong();
            }
            return base.ResolveContractConverter(objectType);
        }
    }

    public class JsonConverterLong : JsonConverter
    {
        /// <summary>
        /// 是否可以转换
        /// </summary>
        /// <param name="objectType"></param>
        /// <returns></returns>
        public override bool CanConvert(Type objectType)
        {
            return true;
        }

        /// <summary>
        /// 读json
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="objectType"></param>
        /// <param name="existingValue"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if ((reader.ValueType == null || reader.ValueType == typeof(long?)) && reader.Value == null)
            {
                return null;
            }
            else
            {
                long.TryParse(reader.Value != null ? reader.Value.ToString() : "", out long value);
                return value;
            }
        }

        /// <summary>
        /// 写json
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="serializer"></param>
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (value == null || Convert.ToInt64(value) < 9007199254740991)
                writer.WriteValue(value);
            else
                writer.WriteValue(value + "");
        }
    }
}
